//=======================================================
//  Input Bicubic Data into RAM
//=======================================================

module lvds_input(
	// CLOCK & RESET //
	 input 		          		iclk
    ,input                      reset_n
	// Internal CONTROL //
    ,input      [11 -1: 0]      weight_in  //2047>1920
    ,input      [11 -1: 0]      height_in  //2047>1080
	// CONTROL & DATA //
    ,input                      indata_valid
    ,input      [24 -1: 0]      indata
    ,output reg                 dout_enable
    // To lvds_output module
    ,output reg                 switch_req
    ,input                      switch_ack
    // RGB RAM Interface
    ,output reg                 lvds_write
    ,output reg [12 -1: 0]      lvds_waddr
    ,output reg [24 -1: 0]      lvds_wdata
);

//=======================================================
//  Local parametr 
//=======================================================
localparam      RAM0_BASE = 0;
localparam      RAM1_BASE = 2048;

//=======================================================
//  REG/WIRE declarations
//=======================================================
//! reg     [22 -1: 0]      pixel_count;
reg     [11 -1: 0]      LinePix_addr;
reg     [11 -1: 0]      line_count; //2047
reg     [12 -1: 0]      base_addr; //4095

reg     [11 -1: 0]      weight;  //2047>1920
reg     [11 -1: 0]      height;  //2047>1080

reg                     indata_valid_d;
reg     [12 -1: 0]      count;
reg     [12 -1: 0]      count_num;
reg     [12 -1: 0]      dout_count;
//=======================================================
//  Structural coding
//=======================================================
// register the frame height and weight at the vs_posPulse.
always@(posedge iclk or negedge reset_n)
begin
  if(!reset_n) begin
    weight <= 0;
    height <= 0;
//  end else if(vs_posPulse) begin
  end else begin
    weight <= weight_in;
    height <= height_in;
  end
end

//-- counter the input data number
always@(posedge iclk or negedge reset_n)
begin
  if(!reset_n) begin
    LinePix_addr <= 0;
  end else if (LinePix_addr == (weight -1)) begin
    LinePix_addr <= 0;
  end else if (indata_valid) begin
    LinePix_addr <= LinePix_addr + 1'b1;
  end
end

//-- counter the hs line number
always@(posedge iclk or negedge reset_n)
begin
  if(!reset_n) begin
    indata_valid_d <= 0;
  end else begin
    indata_valid_d <= indata_valid;
  end
end
assign indata_valid_negPulse = (!indata_valid) & indata_valid_d;

always@(posedge iclk or negedge reset_n)
begin
  if(!reset_n) begin
    line_count <= 0;
  end else if (line_count == (height -1) && indata_valid_negPulse) begin
    line_count <= 0;
  end else if (indata_valid_negPulse) begin
    line_count <= line_count + 1'b1;
  end
end

//-- generete the base_addr
always@(posedge iclk or negedge reset_n)
begin
  if(!reset_n) begin
    base_addr <= RAM0_BASE;
  end else if (line_count[0] == 1'b0) begin
    base_addr <= RAM0_BASE;
  end else if (line_count[0] == 1'b1) begin
    base_addr <= RAM1_BASE;
  end
end

//-- generate the lvds ram interface
always@(posedge iclk or negedge reset_n)
begin
  if(!reset_n) begin
    lvds_write <= 0;
    lvds_waddr <= 0;
    lvds_wdata <= 0;
  end else if (indata_valid) begin
    lvds_write <= 1;
    lvds_waddr <= {base_addr + LinePix_addr};
    lvds_wdata <= indata;
  end else begin
    lvds_write <= 0;
    lvds_waddr <= 0;
    lvds_wdata <= 0;
  end
end

//-- generate the hs switch signals 
always@(posedge iclk or negedge reset_n)
begin
  if(!reset_n) begin
    switch_req <= 0;
  end else if (switch_ack) begin
    switch_req <= 0;
  end else if (indata_valid_negPulse) begin
    switch_req <= 1;
  end
end

//-- generate the dout enable
//! always@(posedge iclk or negedge reset_n)
//! begin
//!   if(!reset_n) begin
//!     count <= 0;
//!   end else if(indata_valid_negPulse) begin
//!     count <= 0;
//!   end else begin
//!     count <= count + 1'b1;
//!   end
//! end
//! 
//! always@(posedge iclk or negedge reset_n)
//! begin
//!   if(!reset_n) begin
//!     count_num <= 0;
//!   end else if (indata_valid_negPulse) begin
//!     if(line_count == (height -4)) begin
//!       count_num <= count;
//!     end else if(line_count == 0) begin
//!       count_num <= 0;
//!     end
//!   end
//! end
//! 
//! always@(posedge iclk or negedge reset_n)
//! begin
//!   if(!reset_n) begin
//!     dout_count <= 0;
//! //  end else if((line_count >= (height -3)) && (line_count < (height -1))) begin
//!   end else if(line_count >= (height -3)) begin
//!     if(dout_count == count_num) begin
//!       dout_count <= 0;
//!     end else begin
//!       dout_count <= dout_count + 1'b1;
//!     end
//!   end else begin
//!     dout_count <= 0;
//!   end
//! end
//! 
always@(posedge iclk or negedge reset_n)
begin
  if(!reset_n) begin
    dout_enable <= 1;
//!  end else if((line_count >=0) && (line_count < (height -3))) begin
//!    dout_enable <= 1;
//!  end else begin
//!    if(dout_count < (count_num - weight -1)) begin
//!      dout_enable <= 0;
//!    end else if((dout_count >= (count_num - weight -1)) && (dout_count < count_num)) begin
//!      dout_enable <= 1;
//!    end
  end
end

endmodule

